/**
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE-MIT file in the root directory of this source tree.
 */

import type { TurboModuleContext } from '../../RNOH/TurboModule';
import { TurboModule } from '../../RNOH/TurboModule';
import promptAction from '@ohos.promptAction';
import { RNOHLogger } from '../../RNOH/RNOHLogger';
import abilityAccessCtrl, { PermissionRequestResult } from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';
import { BusinessError } from "@kit.BasicServicesKit"
import { common } from '@kit.AbilityKit';
import Want from '@ohos.application.Want';

export type PermissionConstants =
    | 'android.permission.READ_CALENDAR'
    | 'android.permission.WRITE_CALENDAR'
    | 'android.permission.CAMERA'
    | 'android.permission.READ_CONTACTS'
    | 'android.permission.WRITE_CONTACTS'
    | 'android.permission.GET_ACCOUNTS'
    | 'android.permission.ACCESS_BACKGROUND_LOCATION'
    | 'android.permission.ACCESS_FINE_LOCATION'
    | 'android.permission.ACCESS_COARSE_LOCATION'
    | 'android.permission.RECORD_AUDIO'
    | 'android.permission.READ_PHONE_STATE'
    | 'android.permission.CALL_PHONE'
    | 'android.permission.READ_CALL_LOG'
    | 'android.permission.WRITE_CALL_LOG'
    | 'com.android.voicemail.permission.ADD_VOICEMAIL'
    | 'android.permission.USE_SIP'
    | 'android.permission.PROCESS_OUTGOING_CALLS'
    | 'android.permission.BODY_SENSORS'
    | 'android.permission.SEND_SMS'
    | 'android.permission.RECEIVE_SMS'
    | 'android.permission.READ_SMS'
    | 'android.permission.RECEIVE_WAP_PUSH'
    | 'android.permission.RECEIVE_MMS'
    | 'android.permission.READ_EXTERNAL_STORAGE'
    | 'android.permission.WRITE_EXTERNAL_STORAGE'


const PermissionAndroidForHarmony = {
  "android.permission.READ_CALENDAR": "ohos.permission.READ_CALENDAR",
  "android.permission.WRITE_CALENDAR": "ohos.permission.WRITE_CALENDAR",
  "android.permission.CAMERA": "ohos.permission.CAMERA",
  "android.permission.READ_CONTACTS": "ohos.permission.READ_CONTACTS",
  "android.permission.WRITE_CONTACTS": "ohos.permission.WRITE_CONTACTS",
  "android.permission.GET_ACCOUNTS": "ohos.permission.READ_CONTACTS",

  "android.permission.ACCESS_FINE_LOCATION": "ohos.permission.LOCATION",
  "android.permission.ACCESS_COARSE_LOCATION": "ohos.permission.APPROXIMATELY_LOCATION",
  "android.permission.ACCESS_BACKGROUND_LOCATION": "ohos.permission.LOCATION_IN_BACKGROUND",

  "android.permission.RECORD_AUDIO": "ohos.permission.MICROPHONE",
  "android.permission.READ_PHONE_STATE": "ohos.permission.GET_DEVICE_INFO", // 未适配
  "android.permission.CALL_PHONE": "ohos.permission.PLACE_CALL", // 未适配 需申请权限
  "android.permission.READ_CALL_LOG": "ohos.permission.READ_CALL_LOG", // 未适配 需申请权限
  "android.permission.WRITE_CALL_LOG": "ohos.permission.WRITE_CALL_LOG", // 未适配 需申请权限

  "com.android.voicemail.permission.ADD_VOICEMAIL": "ohos.permission.MANAGE_VOICEMAIL",  // 未适配 需申请权限
  "android.permission.USE_SIP": ["ohos.permission.INTERNET", "ohos.permission.MICROPHONE", "ohos.permission.CAMERA"],  // 未适配 需测试
  "android.permission.PROCESS_OUTGOING_CALLS": "ohos.permission.READ_TELEPHONY_STATE",  // 未适配 需测试
  "android.permission.BODY_SENSORS": "ohos.permission.READ_HEALTH_DATA",
  "android.permission.SEND_SMS": "ohos.permission.SEND_MESSAGES", // 未适配 需申请权限

  "android.permission.RECEIVE_SMS": "ohos.permission.RECEIVE_SMS", // 未适配 需申请权限
  "android.permission.READ_SMS": "ohos.permission.READ_MESSAGES", // 未适配 需申请权限
  "android.permission.RECEIVE_WAP_PUSH": "ohos.permission.RECEIVE_WAP_PUSH", // 未适配
  "android.permission.RECEIVE_MMS": "ohos.permission.RECEIVE_MMS", // 未适配 需申请权限
  "android.permission.READ_EXTERNAL_STORAGE": "ohos.permission.STORE_PERSISTENT_DATA",
  "android.permission.WRITE_EXTERNAL_STORAGE": "ohos.permission.STORE_PERSISTENT_DATA",

};

const AndroidStatus = {
  "1": 'granted',
  "-1": 'denied',
  "-2": 'never_ask_again'
}

export interface Rationale {
  title: string;
  message: string;
  buttonPositive: string;
  buttonNegative?: string | undefined;
  buttonNeutral?: string | undefined;
}



export class PermissionsAndroidTurboModule extends TurboModule {
  public static readonly NAME = 'PermissionsAndroid';
  private logger: RNOHLogger;
  private tokenId: number = 0;
  private  NEVER_ASK_AGAIN_MAP;



  constructor(protected ctx: TurboModuleContext) {
    super(ctx);
    this.logger = this.ctx.logger.clone("PermissionsAndroidTurboModule")
    this.NEVER_ASK_AGAIN_MAP = new Map();
  }

  check(permission:PermissionConstants): boolean {
    // 获取用户额tokenID
    try {
      let bundleInfo: bundleManager.BundleInfo =
        bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
      this.tokenId = appInfo.accessTokenId;
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      this.logger.error(`Zzk PermissionsAnroid: Failed to check access token. Code is ${err.code}, message is ${err.message}`)
      return false
    }

    // 获取用户访问权限
    try {
      let atManager = abilityAccessCtrl.createAtManager();
      let hasPermission = atManager.checkAccessTokenSync(this.tokenId, getHarmonyPermissionsKey(permission)[0]);
      this.logger.info("Zzk PermissionsAnroid: hasPermission - permission",hasPermission,getPermissionsStatus(hasPermission))
      return hasPermission === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      this.logger.error(`Zzk PermissionsAnroid: Failed to check access token. Code is ${err.code}, message is ${err.message}`)
      return false
    }
  }

  // 判断且处理数据
  request(permission: PermissionConstants |  Array<PermissionConstants>, rationale: Rationale): Promise<any>{
    const context: common.UIAbilityContext = this.ctx.uiAbilityContext as common.UIAbilityContext;

     // if(permission == 'android.permission.ACCESS_BACKGROUND_LOCATION'){
     //   try{
     //     if(this.check(permission)) return;
     //     let want: Want = {
     //       action: 'action.settings.app.info',
     //       parameters: {
     //         settingsParamBundleName: context.abilityInfo.bundleName // 例如: 'com.example.myapp'
     //       }
     //     };
     //     console.log("context.abilityInfo.bundleName",context.abilityInfo.bundleName)
     //     context.startAbility(want).then(() => {
     //       console.info('Start settings ability successfully.');
     //     }).catch((err: BusinessError) => {
     //       console.error(`Failed to startAbility. Code: ${err.code}, message: ${err.message}`);
     //     });
     //     return
     //   }catch (e){
     //     console.error(`Failed to startAbility. ${e}`);
     //   }
     // }


    return new Promise((resolve, reject)=>{
      let atManager = abilityAccessCtrl.createAtManager();
      this.logger.info("Zzk PermissionsAnroid: getHarmonyPermissionsKey --- data" , getHarmonyPermissionsKey(permission))
      atManager.requestPermissionsFromUser(context, getHarmonyPermissionsKey(permission))
        .then(async (data)=>{
          let res = await this.requestResultTranslate(data,rationale)
          this.logger.info("Zzk PermissionsAnroid: request --- then" , JSON.stringify(res))
          if(!Array.isArray(permission)){
            let res = await this.requestResultTranslate(data,rationale)
            resolve(Object.values(res)[0])
            return
          }
          resolve(res)
        }).catch(err=>{
          this.logger.error("Zzk PermissionsAnroid: request --- catch" , JSON.stringify(err))
          reject(err)
        })
    })
  }

  // 权限获取结果转换
  async requestResultTranslate(sourceResult,rationale: Rationale){
   try{
     const {authResults, dialogShownResults,permissions} = sourceResult
     const obj = {};
     for (let i = authResults.length - 1; i >= 0; i--) {
       let dialogShownResult = dialogShownResults[i]
       let permission = permissions[i]
       // 如果已经被拒绝两次，或者点击了不再访问
       // if(this.NEVER_ASK_AGAIN_MAP[permission]) continue;
       let authResult = authResults[i]
       this.logger.info("Zzk requestResultTranslate: " , dialogShownResult,permission,authResult)

       //   场景一： authResult 为 -1 表示用户未授权，dialogShownResult 为 true 表示用户拒绝了
       if(dialogShownResult && authResult === -1){
         // return
         obj[permission] = getPermissionsStatus(-1);
       }

       //   场景二： authResult 为 -1 表示用户未授权，dialogShownResult 为 false 表示应用没有被授权且没有向用户展示请求授权的弹框
       if(!dialogShownResult && authResult === -1){
         let res = await this.openPermissionsSetting(permission)
         // if(res == 'denied'){
         //   this.showPermissionAlert(permission, rationale)
         // }
         obj[permission] = res
       }

       //   场景三： authResult 为 0 表示用户已授权
       if(authResult === 0){
         obj[permission] = getPermissionsStatus(1);
       }

       //   场景四： authResult 为 2 表示请求失败
       if(authResult === 2){
         obj[permission] = getPermissionsStatus(-1);
       }
     }
     this.logger.info("Zzk requestResultTranslate: obj" , obj)
     return Promise.resolve(obj)
   } catch (err) {
     this.logger.info("Zzk PermissionsAnroid: !dialogShownResult && authResult === -1" , JSON.stringify(err))
     return Promise.resolve(err)
   }
  }

  async openPermissionsSetting(permission: PermissionConstants |  Array<PermissionConstants>){
    try{
      const context: common.UIAbilityContext = this.ctx.uiAbilityContext as common.UIAbilityContext;
      let atManager = abilityAccessCtrl.createAtManager();
      atManager.requestPermissionOnSetting(context,getHarmonyPermissionsKey(permission)).then((data: Array<abilityAccessCtrl.GrantStatus>) => {
        this.logger.info("Zzk PermissionsAnroid: openPermissionsSetting --- data" , JSON.stringify(data))
        return Promise.resolve(getPermissionsStatus(data[0]))
      }).catch((err: BusinessError) => {
        this.logger.error("Zzk PermissionsAnroid: openPermissionsSetting --- data --- err" , JSON.stringify(err));
        return Promise.resolve(getPermissionsStatus(-1))
      });
    } catch (e) {
      return Promise.resolve(getPermissionsStatus(-1))
    }
  }

  async showPermissionAlert(permission:string, rationale: Rationale){
    if(!rationale) return

    try {
      let btnList = [
        {
          value: rationale.buttonPositive,
          action: this.handleSubmit
        },
      ];

      //  点击取消
      if(rationale.buttonNegative){
        btnList.push(
          {
            value: rationale.buttonNegative,
            // action: ()=> this.handleNeverAskAgain(permission)
            action:()=>{
              console.info('zzk permissionandroid ==> buttonNegative')
            }
          },
        )
      }

      //  点击不在询问
      if(rationale.buttonNeutral){
        btnList.push(
          {
            value: rationale.buttonNeutral,
            action:()=> this.handleNeverAskAgain(permission)
          },
        )
      }

      let uiCtx = this.ctx.rnInstance.getUIContext()
      uiCtx.showAlertDialog(
        {
          title: rationale.title,
          message: rationale.message,
          autoCancel: true,
          alignment: DialogAlignment.Center,
          gridCount: 4,
          showInSubWindow: true,
          isModal: true,
          offset: { dx: 0, dy: -20 },
          buttons: btnList,
          cancel: () => {
            console.info('zzk permissionandroid ==> cancel')
          },
          onWillDismiss: (dismissDialogAction) => {
            console.info('zzk permissionandroid ==> onWillDismiss')
          }
        }
      )
    }catch (err) {

    }
  }

  handleNeverAskAgain(permission:string){
    this.NEVER_ASK_AGAIN_MAP[permission] = true;
  }

  handleSubmit(){}

   requestMultiple(permissions: Array<PermissionConstants>, rationale: Rationale):Promise<any>{
    return new Promise(async (resolve, reject)=>{
      try {
        const res = await this.request(permissions, rationale)
        resolve(res)
      } catch (reject) {
        reject({})
      }
    })
  }
}

function getHarmonyPermissionsKey(key: string | Array<string>){
  if(Array.isArray(key)){
    let keys:Array<String> =[];
    key.forEach((item:string)=>{
      let value =  PermissionAndroidForHarmony[item]
      if(value) {
        Array.isArray(value) ? keys.push(...value) : keys.push(value)
      }
    })
    return keys
  }
  return [PermissionAndroidForHarmony[key]]
}

function getPermissionsStatus(key:number) : string{
  return AndroidStatus[key] || 'never_ask_again'
}